package UI

// squareDrawing 通过解析Quadrilateral在终端中渲染一个四边形
// @parma ql: 目标渲染的四边形
// @return 渲染是否成功
func squareDrawing(ql *Quadrilateral) bool {

	style := ql.style
	cWidth, cHeight := getCanvasSize(ql)

	oldVolume := ql.volume

	if style.AutoSize {
		if ql.volume.Width == Auto {
			ql.volume.Width = cWidth
		}

		if ql.volume.Height == Auto {
			ql.volume.Height = cHeight
		}
	}

	parent := ql.parent
	position := ql.position
	volume := ql.volume

	cTop := 0
	cLeft := 0
	cRight := 0
	cBottom := 0
	yStart := position.totalY
	xStart := position.totalX
	yEnd := yStart + volume.Height
	xEnd := xStart + volume.Width

	basicsX := ""
	basicsY := ""

	globalBuf.WriteString(hiddenCursor)

	if parent != nil {
		pPosition, _ := parent.GetPosition()

		cTop = pPosition.totalY
		cLeft = pPosition.totalX
		cRight = cLeft + cWidth
		cBottom = cTop + cHeight

		if position.X > cWidth || position.Y > cHeight || position.X+volume.Width <= 0 || position.Y+volume.Height <= 0 { //不会在父节点中渲染
			return false
		}
	} else {
		cRight = SysWidth
		cBottom = SysHeight
	}

	if position.Type.Center != None { //解析position.type.center
		nType := position.Type.Center
		if nType == PositionX || nType == PositionXY {
			xStart = confirmSquareCenter(cRight, volume.Width)
			xEnd = xStart + volume.Width
		}
		if nType == PositionY || nType == PositionXY {
			yStart = confirmSquareCenter(cBottom, volume.Height)
			yEnd = yStart + volume.Height
		}
	}

	if position.Type.Right != None { //解析position.type.right center和right同时存在，right权重更改
		nType := position.Type.Right
		if nType == PositionX || nType == PositionXY {
			xEnd = confirmSquareEnd(position.X, cRight)
			xStart = xEnd - volume.Width
		}
		if nType == PositionY || nType == PositionXY {
			yEnd = confirmSquareEnd(position.Y, cBottom)
			yStart = yEnd - volume.Height
		}
	}

	qlYStart := yStart
	qlXStart := xStart
	qlYEnd := yEnd
	qlXEnd := xEnd

	yStart = confirmStartSquare(yStart, cTop) //确定最终渲染位置
	xStart = confirmStartSquare(xStart, cLeft)
	yEnd = confirmEndSquare(yEnd, cBottom)
	xEnd = confirmEndSquare(xEnd, cRight)

	if style.Color != "" {
		globalBuf.WriteString(style.Color)
	}

	if style.BackGroundColor != "" {
		globalBuf.WriteString(style.BackGroundColor)
	}

	if style.BorderColor != "" {
		basicsY = style.BorderColor
		basicsX = style.BorderColor
	}

	if style.BorderType != None { //对样式的解析
		switch style.BorderType {
		case ContinuousLine:
			basicsX += "-"
			basicsY += "|"
			break
		case DottedLine:
			basicsX += "."
			basicsY += "."
		}
	}

	if style.BorderColor != "" && style.Color != "" {
		basicsY += style.Color
		basicsX += style.Color
	}

	endLinePositionY := qlYEnd - 1
	endLinePositionX := qlXEnd - 1
	textIndex := 0
	for i := yStart; i < yEnd; i++ { //渲染y
		globalBuf.WriteString(setCursorPosition(uint32(xStart)+1, uint32(i)+1)) //定位光标
		for k := xStart; k < xEnd; k++ {
			if (i == qlYStart || i == endLinePositionY) && style.BorderType != None {
				globalBuf.WriteString(basicsX)
			} else if (k == qlXStart || k == endLinePositionX) && style.BorderType != None {
				globalBuf.WriteString(basicsY)
			} else if style.ShowText && textIndex < len(ql.text) {
				globalBuf.WriteByte(ql.text[textIndex])
				textIndex++
			} else {
				globalBuf.WriteByte(' ')
			}
		}
	}
	if style.AutoSize { //动态计算完宽高后重新归置
		ql.volume = oldVolume
	}

	globalBuf.WriteString(closeAllProperties)

	return true
}

// confirmStartSquare 辅助函数，辅助squareDrawing函数确定渲染起点
// @parma positionX: 当前元素起点，start: 可渲染起点
func confirmStartSquare(positionX int, start int) int {
	if (positionX < start || positionX <= 0) && start <= 0 {
		return 0
	} else if positionX < start && start > 0 {
		return start
	} else {
		return positionX
	}
}

// confirmEndSquare 辅助函数，辅助squareDrawing函数确定渲染终点
// @parma positionX: 当前元素终点，start: 可渲染终点
func confirmEndSquare(positionX int, end int) int {
	if (positionX > end || positionX >= SysWidth) && end >= SysWidth {
		return SysWidth
	} else if positionX > end && end < SysWidth {
		return end
	} else {
		return positionX
	}
}

// confirmSquareCenter 辅助函数，辅助squareDrawing函数确定相对渲染起点
// @parma pCount: 当前节点偏移量，width: 可渲染画布大小
func confirmSquareCenter(pCount, size int) int {
	return pCount/2 - size/2
}

// confirmSquareEnd 辅助函数，辅助squareDrawing函数确定相对End渲染起点
// @parma pCount: 当前节点偏移量，width: 可渲染画布大小
func confirmSquareEnd(pCount, size int) int {
	return size - pCount
}

// getCanvasSize 获取当前节点可渲染的画布大小，一般为其父节点的大小
// @parma node: 要获取的节点
// @return 宽，高
func getCanvasSize(node Node) (int, int) {
	parent, _ := node.GetParent()
	if parent == nil {
		return SysWidth, SysHeight
	}
	style, _ := parent.GetStyle()
	volume, _ := parent.GetVolume()
	if style.AutoSize {
		return getCanvasSize(parent)
	} else {
		return volume.Width, volume.Height
	}
}
